const { Buffer } = require('buffer')
const fs = require('fs/promises')

;(async () => {
  const createFile = async (path) => {
    try {
      // we want to check whether or not we already have a file with the same name
      const existingFileHandle = await fs.open(path, 'r')
      existingFileHandle.close()
      // we already have a file with the same name
      return console.log(`The file ${path} already exists`)
    } catch (err) {
      // we don't have a file with the same name
      const newFileHandle = await fs.open(path, 'w')
      console.log('A new file was successfully created')
      return newFileHandle.close()
    }
  }

  const deleteFile = async (path) => {
    try {
      // rm delete everything you want
      // rmdir delete only empty directories
      await fs.unlink(path)
      console.log('The file was successfully deleted')
    } catch (err) {
      console.log(`The file ${path} does not exist`)
    }
  }

  const renameFile = async (oldFilePath, newFilePath) => {
    try {
      await fs.rename(oldFilePath, newFilePath)
      console.log('The file was successfully renamed')
    } catch (err) {
      if (err.code === 'ENOENT') {
        console.log(`The file ${oldFilePath} does not exist`)
      } else {
        console.log('An error occurred while renaming the file')
        console.log(err)
      }
    }
  }

  const addFile = async (path, content) => {
    try {
      // a append
      // w write
      await fs.appendFile(path, content)
      console.log('The file was successfully appended')
    } catch (err) {
      console.log(`The file ${path} does not exist`)
    }
  }

  // commands
  const CREATE_FILE = 'create a file'
  const DELETE_FILE = 'delete the file'
  const RENAME_FILE = 'rename the file'
  const ADD_TO_FILE = 'add to the file'

  const commandFileHandler = await fs.open('./command.txt', 'r')

  commandFileHandler.on('change', async () => {
    // get the stat of the file
    const size = (await commandFileHandler.stat()).size

    // the location at which we want to start filling our buffer
    const offset = 0
    // the position that we want to start reading the file
    const position = 0
    // allocate our buffer with the size of the file
    const buff = Buffer.alloc(size)
    // how many bytes we want to read
    const length = buff.length

    await commandFileHandler.read(buff, offset, length, position)

    // create a file
    // create a file <path>
    const command = buff.toString().trim()
    if (command.includes(CREATE_FILE)) {
      const path = command.substring(CREATE_FILE.length + 1)
      createFile(path)
    }

    // delete a file
    // delete a file <path>
    if (command.includes(DELETE_FILE)) {
      const path = command.substring(DELETE_FILE.length + 1)
      deleteFile(path)
    }

    // rename a file
    // rename a file <path> to <new-path>
    if (command.includes(RENAME_FILE)) {
      const _idx = command.indexOf(' to ')
      const oldFilePath = command.substring(RENAME_FILE.length + 1, _idx)
      const newFilePath = command.substring(_idx + 4)
      renameFile(oldFilePath, newFilePath)
    }

    // add a file
    // add a file <path> this content: <content>
    if (command.includes(ADD_TO_FILE)) {
      const _idx = command.indexOf(' this content: ')
      const path = command.substring(ADD_TO_FILE.length + 1, _idx)
      const content = command.substring(_idx + 15)
      addFile(path, content)
    }
  })
  const watcher = fs.watch('./command.txt')

  for await (const event of watcher) {
    if (event.eventType === 'change') {
      commandFileHandler.emit('change')
    }
  }
})()
